package com.rede.didiok.user.web;

import java.util.List;
import java.util.Set;

import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import com.rede.didiok.common.dto.user.UserDto;
import com.rede.didiok.common.dto.user.UserLoginDto;
import com.rede.didiok.common.dto.user.UserRegistDto;
import com.rede.didiok.common.enums.BizCodeEnum;
import com.rede.didiok.common.exception.ThrowableUtils;
import com.rede.didiok.common.utils.R;
import com.rede.didiok.common.utils.ResultUtil;
import com.rede.didiok.common.validator.group.Delete;
import com.rede.didiok.common.validator.group.GetList;
import com.rede.didiok.common.validator.group.Insert;
import com.rede.didiok.common.validator.group.Update;
import com.rede.didiok.user.entity.UserEntity;
import com.rede.didiok.user.exception.MobileExsitException;
import com.rede.didiok.user.exception.UserNameExistException;
import com.rede.didiok.user.service.UserService;


/**
 * 用户表
 *
 * @author Rede
 * @email didiok@foxmail.com
 * @date 2023-08-07 18:21:17
 */
@Slf4j
@RestController
@RequestMapping("user/feign/user")
public class UserController {
    @Autowired
    private UserService userService;

    /**
     * 获取带头像的用户Map
     *
     * @param ids
     * @return
     */
    @GetMapping(value = "/getUserAvatarMapByIds")
    R getUserAvatarMapByIds(@RequestParam("ids") List<String> ids){
        return R.ok().setData(userService.getUserAvatarMapByIds(ids));
    }

    /**
     * 获取带头像的用户
     *
     * @param ids
     * @return
     */
    @GetMapping(value = "/listUserNameAndAvatarByUids")
    R listUserNameAndAvatarByUids(@RequestParam("ids") List<String> ids){
        return R.ok().setData(userService.listUserNameAndAvatarByUids(ids));
    }

    /**
     * 通过ids获取用户列表【携带用户头像和背景图片】
     *
     * @param
     */
    @PostMapping(value = "/getUserListAndAvatarByIds")
    R getUserListAndAvatarByIds(@RequestBody Set<String> userUidList){
        return R.ok().setData(userService.getUserListAndAvatarByIds(userUidList));
    }

    /**
     * 通过id获取用户【携带用户头像和背景图片】
     *
     * @param
     */
    @PostMapping("/getUserListAndAvatarById")
    R getUserListAndAvatarById(@RequestParam("userUid") String userUid){
        return R.ok().setData(userService.getUserListAndAvatarById(userUid));
    }

    /**
     * 通过ids获取用户列表【“不”携带用户头像和背景图片】
     *
     * @param
     */
    @PostMapping("/getUserListWithoutAvatarByIds")
    R getUserListWithoutAvatarByIds(@RequestBody Set<String> userUidList){
        return R.ok().setData(userService.getUserListWithoutAvatarByIds(userUidList));
    }
    /**
     * 根据用户uid列表查询用户
     * @param uidList
     * @return
     */
    @GetMapping("/listUserByUids")
    R listUserByUids(@RequestParam("uidList") List<String> uidList){
        List<UserEntity> useList = userService.listUserByUids(uidList);
        return R.ok().setData(useList);
    }

    /**
     * 设置用户头像
     *
     * @return
     */
    @GetMapping("/avatar/set")
    String setUserAvatar(UserEntity user) {
        UserEntity userEntity = userService.setUserAvatar(user);
        return ResultUtil.successWithData(userEntity);
    }

    /**
     * 根据 user 的 uid 查询用户
     * @param uid
     * @return
     */
    @GetMapping("/getById")
    R getUserById(@RequestParam("uid") String uid){
        UserEntity user = userService.getById(uid);
        return R.ok().setData(user);
    }

    /**
     * 用户脱敏【去除敏感信息】
     */
    @GetMapping("/convert")
    String convertUser(UserDto user){
        UserDto userDto = userService.convertUser(user);
        return ResultUtil.successWithData(userDto);
    }

    /**
     * 根据用户名获取用户信息
     *
     * @param userName 用户名
     * @return
     */
    @GetMapping(value = "/getByUserName")
    R getByUserName(@RequestParam("userName") String userName){
        UserEntity userEntity = userService.getByUserName(userName);
        return R.ok().setData(userEntity);
    }

    /**
     * 根据用户昵称获取用户信息
     *
     * @param nickname 用户昵称
     * @return
     */
    @GetMapping(value = "/getByNickname")
    R getByNickname(@RequestParam("nickname") String nickname){
        List<UserEntity> userList = userService.getByNickname(nickname);
        return R.ok().setData(userList);
    }

    /**
     * 第三方登录接口
     * @param user
     * @return
     */
    @PostMapping("/user/user/oauth/login")
    public R oauthLogin(@RequestBody UserDto user){

        UserDto userDto =  userService.oauthLogin(user);
        if(userDto !=null){
            return R.ok().setData(userDto);
        }else{
            return R.error(BizCodeEnum.LOGINACCT_PASSWORD_INVAILD_EXCEPTION.getCode(),BizCodeEnum.LOGINACCT_PASSWORD_INVAILD_EXCEPTION.getMsg());
        }
    }

    /**
     * 登录
     * @param vo
     * @return
     */
    @PostMapping("/login")
    public R login(@RequestBody UserLoginDto vo){

        UserEntity entity =  userService.login(vo);
        if(entity!=null){
            return R.ok().setData(entity);
        }else{
            return R.error(BizCodeEnum.LOGINACCT_PASSWORD_INVAILD_EXCEPTION.getCode(),BizCodeEnum.LOGINACCT_PASSWORD_INVAILD_EXCEPTION.getMsg());
        }
    }

    /**
     * 注册
     * @param vo
     * @return
     */
    @PostMapping("/regist")
    public R regist(@RequestBody UserRegistDto vo){

        try{
            userService.regist(vo);
        }catch (MobileExsitException e){
            return R.error(BizCodeEnum.PHONE_EXIST_EXCEPTION.getCode(),BizCodeEnum.PHONE_EXIST_EXCEPTION.getMsg());
        }catch (UserNameExistException e){
            return R.error(BizCodeEnum.USER_EXIST_EXCEPTION.getCode(),BizCodeEnum.USER_EXIST_EXCEPTION.getMsg());
        }

        return R.ok();
    }


    /**
     * 根据userUids 获取 开启邮件通知 的用户
     *
     * @param
     */
    @PostMapping(value = "/user/feign/notice/listUserStartEmailNotification", produces = MediaType.APPLICATION_JSON_UTF8_VALUE, consumes = "application/json;charset=UTF-8")
    R listUserStartEmailNotification(@RequestBody Set<String> userUids){
        return R.ok().setData(userService.listUserStartEmailNotification(userUids));
    }


    @ApiOperation(value = "获取用户列表", notes = "获取用户列表", response = String.class)
    @PostMapping("/getList")
    public String getList(@Validated({GetList.class}) @RequestBody UserDto userDto, BindingResult result) {

        // 参数校验
        ThrowableUtils.checkParamArgument(result);
        log.info("获取用户列表: {}", userDto);
        return ResultUtil.successWithData(userService.getPageList(userDto));
    }

    @ApiOperation(value = "获取用户记录", notes = "获取用户记录", response = String.class)
    @PostMapping("/getRecords")
    public R getUserPageRecords(@Validated({GetList.class}) @RequestBody UserDto userDto, BindingResult result) {

        // 参数校验
        ThrowableUtils.checkParamArgument(result);
        log.info("获取用户记录: {}", userDto);
        return R.ok().setData(userService.getUserPageRecords(userDto));
    }

    @ApiOperation(value = "新增用户", notes = "新增用户", response = String.class)
    @PostMapping("/add")
    public String add(@Validated({Insert.class}) @RequestBody com.rede.didiok.common.dto.user.UserDto userDto, BindingResult result) {

        // 参数校验
        ThrowableUtils.checkParamArgument(result);
        log.info("新增用户: {}", userDto);
        return userService.addUser(userDto);
    }

    @ApiOperation(value = "编辑用户", notes = "编辑用户", response = String.class)
    @PostMapping("/edit")
    public String edit(@Validated({Update.class}) @RequestBody com.rede.didiok.common.dto.user.UserDto userDto, BindingResult result) {
        // 参数校验
        ThrowableUtils.checkParamArgument(result);
        log.info("编辑用户: {}", userDto);
        return userService.editUser(userDto);
    }

    @ApiOperation(value = "删除用户", notes = "删除用户", response = String.class)
    @PostMapping("/delete")
    public String delete(@Validated({Delete.class}) @RequestBody com.rede.didiok.common.dto.user.UserDto userDto, BindingResult result) {

        // 参数校验
        ThrowableUtils.checkParamArgument(result);
        log.info("删除用户: {}", userDto);
        return userService.deleteUser(userDto);
    }

    @ApiOperation(value = "重置用户密码", notes = "重置用户密码", response = String.class)
    @PostMapping("/resetUserPassword")
    public String resetUserPassword(@Validated({Delete.class}) @RequestBody com.rede.didiok.common.dto.user.UserDto userDto, BindingResult result) {

        // 参数校验
        ThrowableUtils.checkParamArgument(result);
        log.info("重置用户密码: {}", userDto);
        return userService.resetUserPassword(userDto);
    }

//    @AuthorityVerify
//    @OperationLogger(value = "用户积分刷数")
//    @ApiOperation(value = "用户积分刷数", notes = "用户积分刷数", response = String.class)
//    @PostMapping("/flushUserCredits")
//    public String flushUserCredits() {
//        return userService.flushUserCredits();
//    }


    /**
     * 目前引入第三方账号 t_user_account 表，需要将原有的用户信息迁移到这里，从而支持多账号绑定
     *
     * @return
     */
    @ApiOperation(value = "用户第三方账号刷数", notes = "用户第三方账号刷数", response = String.class)
    @PostMapping("/flushUserAccount")
    public String flushUserAccount() {
        return userService.flushUserAccount();
    }

    /**
     * 关闭邮件通知
     *
     * @param userUid
     */
    @GetMapping("/closeEmailNotificationById")
    R closeEmailNotificationById(@RequestParam("userUid") String userUid){
        return R.ok().setData(userService.closeEmailNotificationById(userUid));
    }

    /**
     * at事件通用处理方法
     * @param userUid
     * @param toUserUid
     * @param toUid
     * @param bizUid
     * @param bizType
     * @param message
     * @param isAt
     * @return
     */
    @GetMapping("/atEventHandler")
    R atEventHandler(@RequestParam("userUid") String userUid,
                     @RequestParam("toUserUid") String toUserUid,
                     @RequestParam("toUid") String toUid,
                     @RequestParam("bizUid") String bizUid,
                     @RequestParam("bizType") String bizType,
                     @RequestParam("message") String message,
                     @RequestParam("isAt") boolean isAt){
        return userService.atEventHandler(userUid, toUserUid, toUid, bizUid, bizType, message, isAt);
    }
}
